﻿using System;
using System.Collections.Generic;
//using System.Linq;

namespace FizzBuzz
{

    public delegate TResult func<TArg, TResult>(TArg c);

    static class Enumerable
    {
        // extension methods
        public static IEnumerable<T> Where<T>(this IEnumerable<T> source, func<T, bool> filter)
        {
            foreach (var item in source)
            {
                if (filter(item))
                    yield return item;
            }
        }

        public static IEnumerable<TResult> Select<T, TResult>(this IEnumerable<T> source,
            func<T, TResult> selector)
        {
            foreach (var item in source)
                yield return selector(item);
        }        
    }

    public class Customer
    {
        // automatic properties
        public string CustomerID { get; set; }
        public string ContactName { get; set; }
        public string City { get; set; }    
    }

    public class UnderTheCovers
    {
        public void Main()
        {
            List<Customer> customers = LoadCustomers();

            // query expressions
            // anonymous type
            var query =
                from c in customers
                where c.City == "London"
                select new { CustomerID = c.CustomerID, ContactName = c.ContactName };

            // lambda expression
//            var query = Enumerable.Select(Enumerable.Where(customers, c => c.City == "London"),
//                c => new { CustomerID = c.CustomerID, ContactName = c.ContactName }
//                );

//            var query = customers.Where(c => c.City == "London").Select(c => new { CustomerID = c.CustomerID, ContactName = c.ContactName });

            foreach (var item in query)
            {
                Console.WriteLine("Customer Name:" + item.ContactName);
            }
        }
        
        public static List<Customer> LoadCustomers()
        {
            // object initialisers in collection initialisers
            // variable inference
            var customers = new List<Customer>()
            {
                new Customer() { CustomerID = "ALFKI", ContactName = "Nauman", City = "Berlin" },
                new Customer() { CustomerID = "ALFKJ", ContactName = "Leghari", City = "London" }
            };

            return customers;
        }
    }
}
